import { Effect } from 'dva';
import { Reducer } from 'redux';
import _ from 'lodash';
import { message } from 'antd';
import router from 'umi/router';
import { fetchValidation } from '@/utils';
import { queryMenu } from '../services/menu';

export interface ModelType {
  namespace: string;
  state: any;
  effects: {
    fetchMenu: Effect;
  };
  reducers: {
    save: Reducer;
  };
}

const Model: ModelType = {
  namespace: 'menu',

  state: {
    menuInfo: [],
  },

  effects: {
    * fetchMenu({ payload }, { call, put }) {
      const { pathname, ...params } = payload;
      const response = yield call(queryMenu, params);
      const data = fetchValidation(response);

      if (data) {
        const menuList = response.body.menu_list;

        if (menuList.length === 0) {
          message.warn('抱歉！当前主菜并未配置子菜单！');
        } else {

          const { pathname: currentPath } = window.location;
          if (menuList[0].parent_id === 0 && currentPath !== '/') {
            let parent_id = '10000';

            // 避免在当前菜单页刷新导致页面丢失问题
            menuList.forEach((item: any) => {
              if (currentPath.indexOf(item.target_tab) >= 0 && !item.children) {
                parent_id = item.id;
              }
            });

            yield put({
              type: 'fetchMenu',
              payload: { parent_id, pathname: currentPath  },
            });
          }

          if (!pathname) {
            router.push(menuList[0].uri);
          }

          yield put({
            type: 'save',
            payload: { parent_id: payload.parent_id, value: response.body.menu_list },
          });

          return response;
        }
      }
    },
  },

  reducers: {
    save(state, { payload }) {
      let { menuInfo } = _.cloneDeep(state);
      if (payload.parent_id === 0) {
        menuInfo = payload.value;
      } else {
        const pos = menuInfo.findIndex((menu: any) => menu.id === payload.parent_id);
        menuInfo[pos].children = payload.value;
      }
      return { menuInfo };
    },
  },
};

export default Model;
